<?php


namespace App\Service;


use App\Exceptions\ApiException;
use App\Exceptions\MissParamsException;
use App\HttpController\Service\PointService;
use App\Model\SystemAppModel;
use App\Model\UserExtraModel;
use App\Model\UserModel;
use App\Model\UserProfileModel;
use App\Utility\JwtAuth;
use EasySwoole\FastCache\Cache;
use EasySwoole\ORM\DbManager;
use EasySwoole\ORM\Exception\Exception;
use EasySwoole\WeChat\MiniProgram\MiniProgram;

class LoginService
{

    public static function init($system_app_id = 0)
    {
        $system_app_model = new SystemAppModel();
        $config = $system_app_model->getSystemAppConfigById($system_app_id);
        if (empty($config)) {
            throw new ApiException('获取参数失败');
        }
        $wxa = new MiniProgram;
        $wxa->getConfig()->setAppId(trim($config->app_id))->setAppSecret(trim($config->app_secret));
        return $wxa;
    }

    public static function weappLogin($code, $system_app_id, $raw_data = [])
    {
        $app = self::init($system_app_id);
        $result = $app->auth()->session($code);
        $session_key = $result['session_key'];
        $result = self::decrypt($app, $raw_data, $session_key);
        # print_r($result);


        $ret = [];
        try {
            DbManager::getInstance()->startTransaction();
            // 有unionid
            # $user_model = new UserModel();
            # $user_info = $user_model->getUserInfo([''])
            // 没有unionid
            $user_extra_model = new UserExtraModel();
            $extra_info = $user_extra_model->getExtraInfo(['system_app_id' => $system_app_id, 'open_id' => $result['openId']]);
            if (!empty($extra_info)) {
                // 登录成功
                // getUserInfo
                $user_info = UserModel::create()->where(['id' => $extra_info['user_id']])->field(['name', 'avatar', 'sex'])->get();
                $user_id = $extra_info['user_id'];
                $extra_info['user_info'] = $user_info;
                $ret = self::login($extra_info);
            } else {
                # 新用户
                #
                $create_time = time();
                $user_data = [
                    'name' => $result['nickName'],
                    'sex' => $result['gender'],
                    'city' => $result['city'],
                    'province' => $result['province'],
                    'avatar' => $result['avatarUrl'],
                    'create_time' => $create_time
                ];
                $user = UserModel::create($user_data);
                $user_id = $user->save();

                $extra_data = [
                    'user_id' => $user_id,
                    'system_app_id' => $system_app_id,
                    'open_id' => $result['openId'],
                    'create_time' => $create_time
                ];

                $user_extra = UserExtraModel::create($extra_data);
                $user_extra->save();
                unset($user_data['city'], $user_data['create_time'], $user_data['city'], $user_data['province']);
                $extra_data['user_info'] = $user_data;
                // 添加用户资料记录
                $user_profile = UserProfileModel::create(
                    [
                        'user_id' => $user_id
                    ]
                );
                $user_profile->save();
                // 添加积分
                PointService::addPoint($user_id, 100, 1, '新用户注册赠送积分');

                $ret = self::login($extra_data);

            }
            DbManager::getInstance()->commit();
            $redis = \EasySwoole\RedisPool\Redis::defer('redis');
            $redis->set('user_' . $user_id . '_session_key', $session_key);


        } catch (Exception $e) {
            throw new ApiException($e->getMessage());
        }
        return $ret;
    }

    private static function decrypt($app, $data, $session_key)
    {
        $result = $app->encryptor()->decryptData($session_key, $data['iv'], $data['encryptedData']);
        return $result;
    }

    private static function login($data)
    {
        try {
            $ret = [
                'token' => JwtAuth::createToken(['user_id' => $data['user_id']]),
                'user_info' => $data['user_info']
            ];
        } catch (\EasySwoole\Jwt\Exception $e) {
            throw new ApiException($e->getMessage());
        }
        return $ret;
    }

    public static function getWeappMobile($system_app_id, $user_id, $raw_data)
    {
        $redis = \EasySwoole\RedisPool\Redis::defer('redis');
        $session_key = $redis->get('user_' . $user_id . '_session_key');
        $app = self::init($system_app_id);
        $data = self::decrypt($app, $raw_data, $session_key);
        return $data;
    }

}